package Shared;

import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Random;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.namespace.QName;

@XmlRootElement(name = "Player")
public class Player implements Serializable {
    private static final long serialVersionUID = 7163324428772790722L;
    
    private String _name = "";
    private String _password = "";
    private int _score = 0; //score total des parties
    
    private ArrayList<Party> _parties = new ArrayList<Party>(); //historisation des parties d'un joueur   
    private ArrayList<Card> _cartes = new ArrayList<Card>(); //cartes d'une partie en cours
    
    public Player() {}    
    public Player(String name) { _name=name; }
    public Player(String name, String password) { _name=name; _password=password; }
    
    public void setName(String name) { _name = name; }
    public String getName() { return _name; }
    public String get_password() {	return _password; }
    public void set_password(String _password) { this._password = _password; }

    private String _callback = null; //push messages client->serveur lors d'une partie
    public void setCallback(String callback) { _callback = callback; }
    public String getCallback() { return _callback; }
    
     /**
     * Incremente le score total du joueur
     * @param score
     */
    public void addScore(int score) {
	_score += score;
    }
    
    /**
     * Retourne le score total du joueur (somme des scores de toutes les parties) <br>
     * Utilisé pour calculer le classement des joueur
     * @return score total
     */
    public int getScore() { return _score; }
    
    /**
     * Ajoute une partie à l'historique des parties de l'utilisateur <br>
     * Appelé lorsqu'une partie auquel joue l'utilisateur se termine (= les abandons ne sont pas sauvegardés)
     * @param party
     */
    public void addParty(Party party) {
	_parties.add(party);
    }
    
	/**
     * Comparer password
     * @param password
     * @return vrai si les deux mot de passes sont identiques
     */
    public boolean comparePwd(String password) {
	return _password.contentEquals(password);
    }
    
    /**
     * Donne ses cartes au joueur
     * @param cartes
     */
    public void setMain(ArrayList<Card> cartes) { _cartes = cartes; }
    
    /**
     * Retourne les cartes du joueurs
     */
    public ArrayList<Card> getMain() { return _cartes; }
    
    /**
     * Ajoute des cartes aux cartes du joueur
     * @param carte
     */
    public void addCartes(ArrayList<Card> cartes) { 
	for(Card carte : cartes)
	    _cartes.add(carte); 
    }
    
    /**
     * Ajoute une carte aux cartes du joueur
     */
    public void addCarte(Card carte){
    	_cartes.add(carte);
    }
    
    /**
     * Supprime une carte aux cartes du joueur
     * @param carte
     */
    public void removeCarte(Card carte) { _cartes.remove(carte); }
    
    /**
     * @return nombre de cartes que possède le joueur
     */
    public int getNbCartes() { return _cartes.size(); }
    
    /**
     * Choisit une carte au hasard dans le jeu du joueur
     * @return carte
     */
	public Card getHasardCard() {
		Random rand = new Random();
		int indice = rand.nextInt(getNbCartes());
		return _cartes.get(indice);
	
	}

    // +----------------------------------------------------------------------+
    // | Serializer
    // +----------------------------------------------------------------------+
	public static String serialize(Player player) {
	    try {
        	StringWriter writer = new StringWriter();
        	JAXBContext context = JAXBContext.newInstance(Player.class);
        	Marshaller m = context.createMarshaller();
        	m.marshal(new JAXBElement(new QName(Player.class.getSimpleName()), Player.class, player), writer);
        	return writer.toString();
	    } catch(Exception e) {
		e.printStackTrace();	
	    }
	    return "";
	}
	public static Player deserialize(String input) {
	    try {
        	JAXBContext context = JAXBContext.newInstance(Player.class);
        	Unmarshaller m = context.createUnmarshaller();
        	return (Player)m.unmarshal(new StringReader(input));
	    } catch(Exception e) {
		e.printStackTrace();
	    }
	    return null;
	}
}
